// let Scene = require('./Scene');

let {_Math, Vector3, Matrix4} = require('../math');
let {Camera, Obj3D} = require('../core');
let {ShaderLib,ShaderName} = require('../shader');
let {ResCache, ResItem, ResType} = require('../res');
let parseObj = require('../utils/objParser');
let {loadTexture2d} = require('../utils/textureUtils');

//
let hotkeys = require('hotkeys-js').default;

//-----------------------
// 定义好资源
let ballItem = new ResItem('../assets/ball.obj');
let monkeyItem = new ResItem('../assets/monkey.obj');
let imgItem = new ResItem('../assets/xx.webp', ResType.Image);

let meshCache = {};
let texCache = {};

let _dir = new Vector3();

class TestScene {

    constructor(app, callback) {
        this.gl = app.getGL();

        //----------------------------
        // load res
        ResCache.addRes(ballItem);
        ResCache.addRes(imgItem);
        ResCache.addRes(monkeyItem);

        ResCache.load(() => {
            console.log('---- 加载完 obj 和 images');
            // 可以需要的数据
            meshCache[ballItem.getKey()] = parseObj(ballItem.data);
            meshCache[monkeyItem.getKey()] = parseObj(monkeyItem.data);
            texCache[imgItem.getKey()] = loadTexture2d(this.gl, imgItem.data);
            ShaderLib.installShaders(this.gl, () => {
                // 添加事件
                this.installInput();
                callback();
            });
        });

    }

    installInput(){
        const step = 0.4;

        // TODO:
        // mouse事件
        hotkeys('w',(event,handler)=>{
            let camera = this.camera;
            camera.forward(step);
        });
        hotkeys('s',(event,handler)=>{
            let camera = this.camera;
            camera.forward(-step);
        });
        hotkeys('a',(event,handler)=>{
            let camera = this.camera;
            camera.right(-step);
        });
        hotkeys('d',(event,handler)=>{
            let camera = this.camera;
            camera.right(step);
        });

        // 旋转  z c 绕x 轴旋转
        hotkeys('z',(event,handler)=>{
            this.onCameraDirRotateX(new Vector3(0,-1,0));
        });
        hotkeys('c',(event,handler)=>{
            this.onCameraDirRotateX(new Vector3(0,1,0));
        });

        // q,e  绕世界坐标系的x轴旋转
        hotkeys('q',(event,handler)=>{

        });
        hotkeys('e',(event,handler)=>{

        });
    }

    onCameraDirRotateX(endDir,t = 0.1){
        let camera = this.camera;
        let transform = camera.getTransform();
        let curDir = transform.getDir(_dir);
        console.log('curDir:',curDir.x,curDir.y,curDir.z);
        let pos = transform.getPosition();
        console.log('cameraPos:',pos.x,pos.y,pos.z);
        let next = new Vector3();
        next.lerpVectors(curDir,endDir,t);
        next.normalize();
        camera.getTransform().rotateToWorldDir(next);
    }

    init() {

        this.lstObj = [];

        // init camera
        let fov = 60;
        let near = 0.1;
        let far = 1000;
        let aspect = 800 / 600;
        let camera = this.camera = new Camera();
        camera.setProj(_Math.DEG2RAD * fov, aspect, near, far);
        camera.getTransform().setPosition(0, 2, 10);
        camera.getTransform().rotateToWorldDir(new Vector3(0, -1, -5));
        camera.updateCamera();

        // init obj
        let ball = new Obj3D({
            mesh: meshCache[ballItem.getKey()],
            shaderName: ShaderName.POS_UV,
            texId:texCache[imgItem.getKey()],
        });
        this.lstObj.push(ball);

        // monkey
        let monkey = new Obj3D({
            mesh:meshCache[monkeyItem.getKey()],
            shaderName:ShaderName.POS_UV,
            texId:texCache[imgItem.getKey()],
        });
        this.lstObj.push(monkey);
        monkey.getTransform().setPosition(3,0,0);
    }

    render() {
        // 渲染之前,需要保证数据都更新好
        let camera = this.camera;
        camera.updateCamera();
        this.lstObj.forEach(obj=>{
            obj.getTransform().updateMatrix();
        });

        // 开始渲染
        this.lstObj.forEach(obj => {
            obj.render(camera);
        });
    }

    update(dt){
        // 里面进行更新 obj

    }
}

module.exports = TestScene;
